#pragma once
#include <iostream>
#include <cstdio>
#include <string>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/shm.h>
#include <unistd.h>
#define projid 0x66
#define pathname "."
#define USER "user"
#define CREATER "creater"
using namespace std;


class shm{
public:
     shm(const string &pn, int pd,const string &name,int sz=4097):_name(name),_size(sz)
           {
            _key=ftok(pn.c_str(),pd);
            if(_name==USER) {  get(); }
            else if(_name==CREATER) {  create();}
            else{}
            attach();
           }

         void get(){
            corgshm(IPC_CREAT|0666);
         }

         void create(){
            corgshm(IPC_CREAT|IPC_EXCL|0666);
         }

         int sz(){
            return _size;
         }

         void * address(){
            return _mem_address;
         }
       void  getdata(struct shmid_ds *pds){
             shmctl(_shmid,IPC_STAT,pds);
         }
         void modifyshm(struct shmid_ds *pds){
             shmctl(_shmid,IPC_SET,pds);
               
         }
         

    ~shm(){
        int n=shmdt(_mem_address);
        if(n==-1) EXIT("shmdt");
       if(_name==CREATER) {
        destroy();
        cout<<"~shm success"<<endl;
    }
    }

private:

     void attach(){
         _mem_address=shmat(_shmid,nullptr,0);
         if((long long)_mem_address==-1) EXIT("shmat");
         cout<<"shmat success"<<endl;
     }

     void  corgshm(int k){
       int n= shmget(_key,_size,k);
       if(n==-1) EXIT("shmget");
       _shmid=n;
        cout<<"shmget sucess"<<endl;
      }

      void destroy(){
         int n=shmctl(_shmid,IPC_RMID,nullptr);
         if(n==-1) EXIT("shmctl"); 
         cout<<"shmctl success"<<endl;
      }
     int _key;
     int _shmid;
     string _name;
     int _size;
     void * _mem_address;

};